﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StackExchange.Redis;
using Newtonsoft.Json;
using AzureRedis.Models;
using System.Configuration;
using System.Threading.Tasks;

namespace Mvc5.Controllers
{
    public class InterestsController : Controller
    {
        #region Redis Cache Connection
        static string cacheConnectionString = ConfigurationManager.AppSettings["CacheConnection"].ToString();

        static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
        {
            return ConnectionMultiplexer.Connect(cacheConnectionString);
        });

        static ConnectionMultiplexer Connection => lazyConnection.Value;
        #endregion

        // GET: Interests
        public ActionResult Index()
        {
            IDatabase cache = Connection.GetDatabase();

            var interests = cache
                .HashGetAll("Interests")
                .Select(item => JsonConvert.DeserializeObject<Interest>(item.Value))
                .OrderByDescending(i => i.RequestedOn)
                .ToList();

            return View(interests);
        }

        // GET: Interests/Create
        public ActionResult Create()
        {
            ViewBag.Program = this.Programs;
            ViewBag.Destination = this.Destinations;

            return View();
        }

        // POST: Interests/Create
        [HttpPost]
        public async Task<ActionResult> Create(Interest interest)
        {
            if (ModelState.IsValid)
            {
                IDatabase cache = Connection.GetDatabase();

                interest.Id = Guid.NewGuid();

                HashEntry entry = new HashEntry(
                    interest.Id.ToString(),
                    JsonConvert.SerializeObject(interest));

                await cache.HashSetAsync("Interests", new[] { entry });

                return RedirectToAction("Index");
            }

            ViewBag.Program = this.Programs;
            ViewBag.Destination = this.Destinations;

            return View();
        }

        // GET: Interests/Edit/5
        public async Task<ActionResult> Edit(string id)
        {
            IDatabase cache = Connection.GetDatabase();

            var interest = await cache.HashGetAsync("Interests", id);
            var model = JsonConvert.DeserializeObject<Interest>(interest.ToString());

            ViewBag.Program = this.Programs;
            ViewBag.Destination = this.Destinations;

            return View(model);
        }

        // POST: Interests/Edit/5
        [HttpPost]
        public async Task<ActionResult> Edit(string id, Interest interest)
        {
            if (ModelState.IsValid)
            {
                IDatabase cache = Connection.GetDatabase();

                HashEntry entry = new HashEntry(
                    id,
                    JsonConvert.SerializeObject(interest));

                await cache.HashSetAsync("Interests", new[] { entry });

                return RedirectToAction("Index");
            }

            ViewBag.Program = this.Programs;
            ViewBag.Destination = this.Destinations;

            return View(interest);
        }

        // GET: Interests/Delete/5
        [ActionName("Delete")]
        public async Task<ActionResult> DeleteConfirm(string id)
        {
            IDatabase cache = Connection.GetDatabase();

            var interest = await cache.HashGetAsync("Interests", id);
            var model = JsonConvert.DeserializeObject<Interest>(interest.ToString());

            return View(model);
        }

        // POST: Interests/Delete/5
        [HttpPost]
        public async Task<ActionResult> Delete(string id)
        {
            IDatabase cache = Connection.GetDatabase();

            await cache.HashDeleteAsync("Interests", id);

            return RedirectToAction("Index");
        }

        SelectList Programs => new SelectList(Program.List, "Name", "Name");

        SelectList Destinations => new SelectList(Destination.List.OrderBy(d => d.Name), "Name", "Name");
    }
}
